using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Permissions;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Core.BOL;
using Core.DAL;
using Core.Extentions;
using Core.Utils;
using ScoutNET.Attributes;
using ScoutNET.Helpers;

namespace ScoutNET.Controllers
{
    public class Vote
    {
        public int Sum { get; set; }
        public int Votes { get; set; }
        public int Avg { get; set; }
    }

    public class PhotoController : ApplicationController
    {
        private SectionRepository sr = new SectionRepository();
        private CommentRepository cr = new CommentRepository();
        private RatingRepository rr = new RatingRepository();
        private MyAlbumRepository mr = new MyAlbumRepository();
        private AlbumsRepository ar = new AlbumsRepository();
        private ImagesRepository ir = new ImagesRepository();
        
        #region Views
        [AuthorizeView(ErrorMessageKey = "Galerie_Index_Error_Acces", ShowToCrawler = true)]
        public ActionResult Index(string systemName, int? page, int? ID)
        {
            //Pager
            int totalItems = ir.GetCountImagesByAlbum((int)ID);
            int pageID = (page == null || page == 0) ? 1 : (int)page;
            pageID = (pageID > totalItems - 1) ? totalItems - 1 : pageID - 1;
            tSite_Photos_Image i = ir.GetImagesByAlbumID((int)ID, pageID, 1)[0];

            tSite_Photos_Album a = ar.GetAlbumByID(i.AID);
            List<tSite_Photos_Comment> lComment = cr.GetCommentsByImageID(i.ID);
            string section = sr.GetSectionNameBySystemName(systemName);
            MembershipUser mu = Membership.GetUser(User.Identity.Name);
            if (mu == null)
            {
                mu = Membership.GetUser(ConfigurationManager.AppSettings["AnonymeUser"]); 
            }
            Guid UID = (Guid)mu.ProviderUserKey;
            bool IsAlreadyRate = rr.IsAlreadyRate(i.ID, UID);
            bool IsInAlbum = mr.IsInAlbum(i.ID, UID);

            ViewData["PageTitle"] = Resources.Photo_Index_Title.Replace("[SECTION]", section.ToLower()).Replace("[ALBUM_TITLE]", a.Title).Replace("[CURRENT]", (pageID + 1).ToString()).Replace("[MAX_ITEM]", totalItems.ToString());
            ViewData["MetaTitle"] = a.Title;
            ViewData["PageDescription"] = a.Description + " - Photo " + (pageID + 1).ToString() + "/" + totalItems.ToString();
            ViewData["MetaThumbnail"] = ConfigurationManager.AppSettings["SiteUrl"] + Url.Action("MetaThumbnail", new { controller = "Photo", title = a.Title.ParseUrl(), id = i.ID.ToString() }) + ".jpg";

            string[] saBreadcrumb = new String[4];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Galerie_Index_Breadcrumb.Replace("[SECTION]", section.ToLower()), "SectionIndex", "Index", "Galerie", null, null);
            saBreadcrumb[2] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, a.Title, "SectionDetailsWithTitle", "Index", "Album", new RouteValueDictionary( new { ID = a.ID, Title = a.Title.ParseUrl() }), null);
            saBreadcrumb[3] = Resources.Photos_Index_Breadcrumb.Replace("[PAGE_ID]", (pageID + 1).ToString()).Replace("[TOTAL_ITEMS]", totalItems.ToString());
            ViewData["Breadcrumb"] = saBreadcrumb;

            ViewData["UserType"] = UsersRepository.GetUserType(systemName);

            //Preload Image
            tSite_Photos_Image prevPicture = ir.GetPreviousImage(i.ID, 1, i.AID).SingleOrDefault();
            tSite_Photos_Image nextPicture = ir.GetNextImage(i.ID, 1, i.AID).SingleOrDefault();

            string prealoadUrls = string.Empty;
            if (prevPicture != null)
            {
                prealoadUrls = "\"" + Url.RouteUrl("ImageResizer", new { controller = "Photo", action = "ImageResize", Title = prevPicture.AlbumName.ParseUrl(), id = prevPicture.ID }) + "\"";
            }

            if (nextPicture != null)
            {
                if (!string.IsNullOrEmpty(prealoadUrls))
                {
                    prealoadUrls += ",";
                }
                prealoadUrls += "\"" + Url.RouteUrl("ImageResizer", new { controller = "Photo", action = "ImageResize", Title = nextPicture.AlbumName.ParseUrl(), id = nextPicture.ID }) + "\"";
            }

            ViewData["PrealoadUrls"] = prealoadUrls;

            //Ajax Star rating
            Vote v = this.GetVotesByImageID(i.ID);
            string[] rateValues = ConfigurationManager.AppSettings["RateValues"].Split(',');
            List<RadioButtonListInfo> lRate = new List<RadioButtonListInfo>();
            foreach (string rateValue in rateValues)
            {
                bool isSelected = (v.Avg.ToString() == rateValue) ? true : false;
                lRate.Add(new RadioButtonListInfo(rateValue, string.Empty, isSelected));
            }

            ViewData["rate"] = lRate;
            ViewData["AlreadyRate"] = IsAlreadyRate;
            ViewData["TotalPages"] = totalItems;
            ViewData["TotalItems"] = 1;
            ViewData["Page"] = pageID + 1;
            ViewData["SystemName"] = systemName;
            ViewData["SectionName"] = section;
            ViewData["AlbumTitle"] = a.Title;
            ViewData["AlbumID"] = ID;
            ViewData["Comments"] = lComment;
            ViewData["NumComments"] = lComment.Count;
            ViewData["SectionName"] = systemName;
            ViewData["UserID"] = UID;
            ViewData["Votes"] = v;
            ViewData["IsInAlbum"] = IsInAlbum;

            return View("Index", i);

        }

        [Authorize(Roles = "Animateur,C.U")]
        public ActionResult Delete(int ID)
        {
            int AID = ir.GetAlbumIDByImageID(ID);
            ViewData["IsDefaultImageOfAlbum"] = ir.IsDefaultImageOfAlbum(ID);
            ViewData["IsLatestImageOfAlbum"] = ir.IsLatestImageOfAlbum(ID);
            ViewData["ID"] = ID.ToString();
            ViewData["AID"] = AID.ToString();
            return View();
        }

        [HttpPost]
        [Authorize(Roles = "Animateur,C.U")]
        public EmptyResult Delete(FormCollection fc)
        {
            bool IsDefaultImageOfAlbum = ir.IsDefaultImageOfAlbum(int.Parse(fc["ID"]));
            if (!IsDefaultImageOfAlbum)
            {
                ir.DeletePictureByImageID(int.Parse(fc["ID"]));
                ir.Save();
            }

            return new EmptyResult();
        }

        [Authorize]
        public ActionResult CreateComment(string systemName, int ID)
        {
            ViewData["IID"] = ID;
            ViewData["SectionName"] = systemName;
            return View("Comment");
        }

        [Authorize]
        [HttpPost]
        public EmptyResult CreateComment(FormCollection fc)
        {
            if (ValidateComment(fc))
            {
                int ID = int.Parse(fc["IID"].ToString());
                MembershipUser mu = Membership.GetUser(User.Identity.Name);
                int albumID = ir.GetAlbumIDByImageID(ID);

                tSite_Photos_Comment c = new tSite_Photos_Comment();
                c.InsertDate = DateTime.Now.GetNowTimeByTimeZone();
                c.SID = sr.GetSectionID(fc["SectionName"]);
                c.IID = ID;
                c.UID = (Guid)mu.ProviderUserKey;
                c.AID = albumID;
                c.Comment = fc["Comment"];
                cr.InsertComment(c);
                cr.Save();
            }

            return new EmptyResult();
        }

        public ActionResult GetComments()
        {
            return new EmptyResult();
        }

        [Authorize]
        [HttpPost]
        public ActionResult GetComments(FormCollection fc)
        {
            int IID = int.Parse(fc["IID"]);

            List<tSite_Photos_Comment> lComment = cr.GetCommentsByImageID(IID);
            var query = (from c in lComment
                         select new 
                         {
                             UserID = c.UID,
                             UserName = c.aspnet_User.UserName,
                             InsertDate = c.InsertDate,
                             Text = c.Comment
                         }).ToList();

            return this.Json(query);
        }

        public EmptyResult RateImage()
        {
            return new EmptyResult();
        }

        [Authorize]
        [HttpPost]
        public JsonResult RateImage(FormCollection fc)
        {
            int IID = int.Parse(fc["IID"]);
            tSite_Photos_Rating r = new tSite_Photos_Rating();
            r.IID = IID;
            r.InsertDate = DateTime.Now.GetNowTimeByTimeZone();
            r.Rate = Convert.ToInt32(fc["rate"]);
            r.UID = new Guid(fc["UID"]);
            rr.InsertRating(r);
            rr.Save();

            Vote v = this.GetVotesByImageID(IID);

            return this.Json(new { votes = v.Votes, sum = v.Sum, avg = v.Avg }, JsonRequestBehavior.AllowGet);
        }

        public EmptyResult AddToMyAlbum(string systemName)
        {
            return new EmptyResult();
        }

        [Authorize]
        [HttpPost]
        public String AddToMyAlbum(string systemName, int? page, Guid? ID, FormCollection fc)
        {
            tSite_Photos_MyAlbum ma = new tSite_Photos_MyAlbum();
            ma.AID = int.Parse(fc["AID"]);
            ma.IID = int.Parse(fc["IID"]);
            ma.InsertDate = DateTime.Now.GetNowTimeByTimeZone();
            ma.UID = new Guid(fc["UID"]);
            mr.InsertMyAlbum(ma);
            mr.Save();

            return mr.GetCountImagesByUserID(ma.UID).ToString();
        }

        [Authorize(Roles = "Animateur,C.U")]
        [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
        public FileResult RightRotationImage(int ID, string title)
        {
            tSite_Photos_Image img = ir.GetImageByID(ID);
            Dictionary<string, int> imageSize = Imaging.GetImageSize(ImageMode.GalleryPhoto);
            string picturePath = HttpContext.Server.MapPath(ConfigurationManager.AppSettings["GalleryPath"] + img.AID.ToString("D6") + "/" + img.ImageName.ToString() + ".jpg");

            Imaging.DeleteImageCached(img.ID);

            byte[] baImage = Core.Utils.Files.FileToArray(picturePath);
            baImage = Imaging.RightRotateImage90(baImage);
            Files.ByteArrayToFile(picturePath, baImage);
            baImage = Imaging.ResizeImageToPortrait(baImage, imageSize["W"], imageSize["H"]);
            baImage = Imaging.Watermark(baImage, ConfigurationManager.AppSettings["Watermark"]);

            string path = Url.RouteUrl("ImageResizer", new { action = "ImageResize", controller = "Photo", title = img.AlbumName.ParseUrl(), ID = img.ID });
            HttpResponse.RemoveOutputCacheItem(path);

            return new FileContentResult(baImage, "image/jpeg");
        }

        [Authorize(Roles = "Animateur,C.U")]
        [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
        public FileResult LeftRotationImage(int ID, string title)
        {
            tSite_Photos_Image img = ir.GetImageByID(ID);
            Dictionary<string, int> imageSize = Imaging.GetImageSize(ImageMode.GalleryPhoto);
            string picturePath = HttpContext.Server.MapPath(ConfigurationManager.AppSettings["GalleryPath"] + img.AID.ToString("D6") + "/" + img.ImageName.ToString() + ".jpg");

            Imaging.DeleteImageCached(img.ID);

            byte[] baImage = Core.Utils.Files.FileToArray(picturePath);
            baImage = Imaging.LeftRotateImage90(baImage);
            Files.ByteArrayToFile(picturePath, baImage);
            baImage = Imaging.ResizeImageToPortrait(baImage, imageSize["W"], imageSize["H"]);
            baImage = Imaging.Watermark(baImage, ConfigurationManager.AppSettings["Watermark"]);

            string path = Url.RouteUrl("ImageResizer", new { action = "ImageResize", controller = "Photo", title = img.AlbumName.ParseUrl(), ID = img.ID });
            HttpResponse.RemoveOutputCacheItem(path);

            return new FileContentResult(baImage, "image/jpeg");
        }

        [AuthorizeView(ShowToCrawler = true)]
        [OutputCache(CacheProfile="Photo")]
        [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
        public ActionResult ImageResize(int? ID, string title)
        {
            if (ID != null)
            {
                byte[] baImage = Imaging.GetResizedImage((int)ID, ImageMode.GalleryPhoto, false);

                return new FileContentResult(baImage, "image/jpeg");
            }
            else
            {
                return View("Error404");
            }
        }

        [OutputCache(CacheProfile="Photo")]
        [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
        public ActionResult MetaThumbnail(int ID, string title)
        {
            tSite_Photos_Image img = ir.GetImageByID(ID);

            if (img != null)
            {
                byte[] baImage = Imaging.GetResizedImage(img.ID, ImageMode.MyAlbumThumbnail, false, false);

                return new FileContentResult(baImage, "image/jpeg");
            }
            else
            {
                return View("Error404");
            }
        }
        #endregion

        #region Methodes
        private bool ValidateComment(FormCollection fc)
        {
            ModelState.SetModelValue("comment", ValueProvider.GetValue("comment"));

            if (String.IsNullOrEmpty(fc["comment"].Trim()))
            {
                ModelState.AddModelError("comment", Resources.Contact_Index_Error_Firstname);
            }

            return ModelState.IsValid;
        }

        private Vote GetVotesByImageID(int ImageID)
        {
            List<tSite_Photos_Rating> lRating = rr.GetRatesByImageId(ImageID);

            var sum = (from p in lRating
                       group p by p.IID into g
                       select new { TotalRate = g.Sum(p => p.Rate) }).SingleOrDefault();
            int votes = lRating.Count;

            Vote v = new Vote();
            v.Avg = 0;
            v.Sum = 0;
            v.Votes = 0;

            if (sum != null)
            {
                if (votes != 0 && sum.TotalRate != 0)
                {
                    v.Avg = sum.TotalRate / votes;
                }
                v.Sum = sum.TotalRate;
                v.Votes = votes;
            }

            return v;
        }
        #endregion
    }
}